package com.tistory.commons.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.net.URLEncoder;
import java.net.URLDecoder;
import  java.text.DecimalFormat;
import java.io.UnsupportedEncodingException;

public class MakeCode
{
    public HashMap       enMap       = new HashMap();
    public HashMap       deMap       = new HashMap();
    public final double  KEY_LENGTH  = 62;
    public MakeCode      tcu;

    public MakeCode()
    {
        String key[]    = {"1","2","3","4","5","6","7","8","9","a",
                            "b","c","d","e","f","g","h","i","j","k",
                            "l","n","m","o","p","q","r","s","t","u",
                            "v","w","x","y","z","A","B","C","D","E",
                            "F","G","H","I","J","K","L","N","M","O",
                            "P","Q","R","S","T","U","V","W","X","Y",
                            "Z","0"};

        String xVal[]   = {"1","2","3","4","5","6","7","8","9","10",
                            "11","12","13","14","15","16","17","18","19","20",
                            "21","22","23","24","25","26","27","28","29","30",
                            "31","32","33","34","35","36","37","38","39","40",
                            "41","42","43","44","45","46","47","48","49","50",
                            "51","52","53","54","55","56","57","58","59","60",
                            "61","62"};

        for(int i=0; i<key.length; i++)
        {
//          if((i+1)==KEY_LENGTH)
//              enMap.put(""+(i+1), key[i]);
//          else
            enMap.put(""+(i+1), key[i]);
            deMap.put(key[i], xVal[i]);
        }
    }

    public String EnCode(String param, int nLevel) throws Exception
    {
        if(nLevel == 1)
        {
            param   = EnCode(param);
        }
        else
        {
            try
            {
                param   = EnCode(param);
                param   = EnXCode(param);
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        return param;
    }
    
    public String DeCode(String param, int nLevel) throws Exception
    {
        try
        {
            if(nLevel == 1)
            {
                param   = DeCode(param);
            }
            else
            {
                param   = DeXCode(param);
                param   = DeCode(param);
            }
        }
        catch(Exception e)
        {
            throw e;
        }

        return param;
    }

    public String EnXCode(String param) throws Exception
    {
        StringBuffer    sb  = new StringBuffer();
        int             nWD = 15;
        int             nPos= 0;

        if(param!=null)
        {
            if(param.length()>1)
            {
                ArrayList       lt  = new ArrayList();
                DecimalFormat   fm  = new DecimalFormat("#");
                
                while(true)
                {
                    String  code    = "";
                    int     nLen    = 0; 

                    if(param.length()>(nPos+nWD))
                    {
                        code    = param.substring(nPos,(nPos+nWD));
                        nPos    += nWD;

                        try
                        {
                            nLen    = code.length() - fm.format(Double.parseDouble(code)).length();

                        }
                        catch(Exception e)
                        {
                            nLen    = 0;
                            throw e;
                        }
                    }
                    else
                    {
                        code    = param.substring(nPos, param.length());
                        nPos    = param.length();

                        nPos        += nWD;

                        try
                        {
                            nLen    = code.length() - fm.format(Double.parseDouble(code)).length();
                        }
                        catch(Exception e)
                        {
                            nLen    = 0;
                            throw e;
                        }
                    }

                    lt.add(getStr("#",nLen)+code);

                    if(nPos >= param.length())
                        break;
                }

                for(int i=0; i<lt.size(); i++)
                {
                    sb.append(inXCode(((String)lt.get(i)) ));
                }
            }
        }
        else
        {
            param   = "";
        }

        return sb.toString();
    }

    private String inXCode(String param) throws Exception
    {
        StringBuffer    sb      = new StringBuffer();
        boolean     flg     = true;
        double          dVal    = 0;
        String          sAppend = "";

        try
        {
            if( param.indexOf("#") > -1 )
            {
                sAppend = param.substring(0,param.lastIndexOf("#")+1);
                param   = param.substring(param.lastIndexOf("#")+1);
            }

            sb.append(sAppend);

            try
            {
                dVal    = Double.parseDouble(param);
            }
            catch(Exception e)
            {
                dVal    = 0;
                throw e;
            }

            if( tcu == null )
                tcu = new MakeCode();

            String      val = "";

            while(flg)
            {
                if(dVal>KEY_LENGTH)
                {
                    try
                    {
                        double  nCur    = dVal%KEY_LENGTH;
                        double  nRmd    = dVal/KEY_LENGTH;

                        if(nRmd>0)
                        {
                            if((int)nCur == 0)
                                val     += "0";
                            else
                                val     += (String) tcu.enMap.get(""+((int) nCur));

                            dVal    = nRmd;
                        }
                        else
                        {
                            if((int)nCur == 0)
                                val     += "0";
                            else
                                val     += (String) tcu.enMap.get(""+((int) nCur));

                            flg = false;
                        }
                    }
                    catch(Exception e)
                    {
                        throw e;
                    }
                }
                else
                {
                    if((int)dVal == 0)
                        val     += "0";
                    else
                        val     += (String) tcu.enMap.get(""+((int) dVal));

                    flg = false;
                }
            }

            sb.append(val);

            for(int i=0; i<(9-val.length()); i++)
            {
                sb.append("0");
            }
        }
        catch(Exception e)
        {
            throw e;
        }

        return sb.toString();
    }

    public String DeXCode(String param) throws Exception
    {
        StringBuffer    sb  = new StringBuffer();
        boolean     flg = true;
        int             nWD = 9;
        int             nPos= 0;

        if(param!=null)
        {
            if(param.length()>1)
            {
                while(flg)
                {
                    String  code    = "";
                    String  sAppend = "";

                    if(param.length()>(nPos+nWD))
                    {
                        code    = param.substring(nPos,(nPos+nWD));

                        if(param.indexOf("#",(nPos+nWD))==(nPos+nWD))
                        {
                            int nCnt    = getCountStr(param.substring((nPos+nWD)),'#');
                            nPos    += nCnt;
                            sAppend = getStr("0", nCnt);
                        }

                        nPos    += nWD;
                    }
                    else
                    {
                        code    = param.substring(nPos,param.length());
                        nPos    = param.length();
                    }

                    try
                    {
                        sb.append(outXCode(code)+sAppend);
                    }
                    catch(Exception e)
                    {
                        throw e;
                    }

                    if(nPos >= param.length())
                        flg = false;
                }
            }
        }
        else
        {
            sb.append("");
        }

        return sb.toString();
    }

    private String outXCode(String param) throws Exception
    {
        double  nRtn    = 0;
        DecimalFormat   fm  = new DecimalFormat("#");

        for(int i=0; i<param.length(); i++)
        {
            String  cd  = param.substring(i,(i+1));

            if(!cd.equals("0"))
            {
                String  sVal    = (String)deMap.get(cd);

                double  multi   = 1;

                for(int j=0; j<i; j++)
                    multi   = multi * KEY_LENGTH;

                try
                {
                    nRtn    += multi * Double.parseDouble(sVal);
                }
                catch(Exception e)
                {
                    throw e;
//                  System.out.println("outXCode Integer.parseInt(sVal); Error");
                }
            }
        }

        return fm.format(nRtn);
    }

    private String EnCode(String param)
    {
        StringBuffer    sb  = new StringBuffer();

        if(param == null)
        {
            sb.append("");
        }
        else
        {
            if(param.length()>0)
            {
                for(int i=0; i<param.length(); i++)
                {
                    String  len = ""+((int)param.charAt(i));
                    sb.append(len.length());
                    sb.append(((int)param.charAt(i)));
                }
            }
        }

        return sb.toString();
    }

    private String DeCode(String param) throws Exception
    {
        StringBuffer    sb  = new StringBuffer();
        int             pos = 0;
        boolean     flg = true;

        if(param!=null)
        {
            if(param.length()>1)
            {
                while(flg)
                {
                    String  sLen    = param.substring(pos,++pos);
                    int     nLen    = 0;

                    try
                    {
                        nLen    = Integer.parseInt(sLen);
                    }
                    catch(Exception e)
                    {
                        nLen    = 0;
                        throw e;
                    }

                    String  code    = "";
                    if((pos+nLen)>param.length())
                        code    = param.substring(pos);
                    else
                        code    = param.substring(pos,(pos+nLen));

                    pos     += nLen;

                    sb.append(((char) Integer.parseInt(code)));

                    if(pos >= param.length())
                        flg = false;
                }
            }
        }
        else
        {
            param   = "";
        }

        return sb.toString();
    }

    public String URLEncoder(String param)
    {
        if(param == null)
            return "";
        else
            return URLEncoder.encode(param);

    }

    public String URLDecoder(String param)
    {
        if(param == null)
            return "";
        else
            return URLDecoder.decode(param);
    }

    //  euc-kr, UTF-8, KSC5601
    public String URLEncoder(String param, String encType)
    {
        if(param == null)
        {
            return "";
        }
        else
        {
            try
            {
                return URLEncoder.encode(param, encType);
            }
            catch (UnsupportedEncodingException e)
            {
                return "";
            }
        }
    }

    //  euc-kr, UTF-8, KSC5601
    public String URLDecoder(String param, String encType)
    {
        if(param == null)
        {
            return "";
        }
        else
        {
            try
            {
                return URLDecoder.decode(param, encType);
            }
            catch (UnsupportedEncodingException e)
            {
                return "";
            }
        }
    }

    public byte[] EnCodeByte(String param)
    {
        byte[]  bt  = null;

        if(param != null)
        {
            bt  = param.getBytes();
        }

        return bt;
    }

    public String DeCodeByte(byte bt[])
    {
        String  sRtn    = null;

        if(bt!=null)
        {
            sRtn    = new String(bt);
        }
        else
        {
            sRtn    = "";
        }

        return sRtn;
    }

    private String nullChk(String param)
    {
        if(param == null)
            return "";
        else
            return param.trim();
    }

    private String getStr(String param, int nCnt)
    {
        StringBuffer    sb  = new StringBuffer();

        for(int i=0; i<nCnt; i++)
            sb.append(param);

        return sb.toString();
    }

    private int getCountStr(String param1, String param2)
    {
        int nCnt    = 0;

        if( param1.indexOf(param2) > -1 )
        {
            for(int i=0; i<param1.length(); i++)
            {
                if(param1.charAt(i) == param2.charAt(0))
                {
                    nCnt++;
                }
                else
                {
                    break;
                }
            }
        }

        return nCnt;
    }

    private int getCountStr(String param1, char param2)
    {
        int nCnt    = 0;

        if( param1.indexOf(param2) > -1 )
        {
            for(int i=0; i<param1.length(); i++)
            {
                if(param1.charAt(i) == param2)
                {
                    nCnt++;
                }
                else
                {
                    break;
                }
            }
        }

        return nCnt;
    }
}